package com.example.dishit.service.recommendation;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

import com.example.dishit.model.dish.DishData;

public class RecommendationGenerator implements IRecommendationGenerator {
    private final Executor thread = Executors.newSingleThreadExecutor();
    
    public void requestRecommendation(final IRecommendationListener callback) {
        thread.execute(new Runnable() {
            public void run() {
            	while(true) {
            		final DishData recommendation = generateRecommendation();
            		if(recommendation != null) {
            			callback.onRecommendation(recommendation);
            			return;
            		}
            	}
            }
        });
    }
    
    private static DishData generateRecommendation() {
        DishData finalRecommendation = null;
        ArrayList<DishData> restaurants = new LocationService().getNearbyRestaurants();
        if (restaurants!=null && restaurants.size() > 0){

        	//Step 1: Return the one rated high by me
  /*  		String userId = MainController.THIS_USER_ID;
    		List<Review> myReviews = null;
    		myReviews = DBProxy.getDishes(userId); //TODO: Uncomment after it compiles
    		
    		for (Iterator<Review> iterator = myReviews.iterator(); iterator.hasNext();) {
				Review review = iterator.next();
				if (review.getRating() > 3){
					String restaurantName = review.getRestaurant().getName();
					for (Iterator<RestaurantRecommendation> iterator2 = restaurants.iterator(); iterator2
							.hasNext();) {
						RestaurantRecommendation restaurantRecommendation =  iterator2.next();
						if (restaurantRecommendation.getRestaurantName().equalsIgnoreCase(restaurantName)){
							recommendation = restaurantRecommendation;
							return recommendation;
						}						
					}
				}				
			}
    		
    		//Step 2: Return the one rated high by my friends
    		
    		List<Dish> friendsDishes = DBProxy.getFollowsDishes(userId);
    		for (Iterator<Dish> iterator = friendsDishes.iterator(); iterator.hasNext();) {
				Dish dish = iterator.next();
				Review review = dish.getReview();
				if (review.getRating() > 3){
					String restaurantName = review.getRestaurant().getName();
					for (Iterator<RestaurantRecommendation> iterator2 = restaurants.iterator(); iterator2
							.hasNext();) {
						RestaurantRecommendation restaurantRecommendation =  iterator2.next();
						if (restaurantRecommendation.getRestaurantName().equalsIgnoreCase(restaurantName)){
							recommendation = restaurantRecommendation;
							return recommendation;
						}						
					}
				}				
			}
    */		
    		//Step 3: No match with my or my friends' "likes". Return the first nearest restaurant
    	//	if (recommendation==null){
        	Random generator = new Random();
    			int index = generator.nextInt(restaurants.size());
    			
    			final DishData recommendation = restaurants.get(index);
    			
    			DishData dishData = new LocationService().getRestaurantDetails(recommendation.getReference());
    			
    			if(dishData == null) return null;
    			
    			final DishData.Builder builder = new DishData.Builder()
													.dishData(recommendation)
													.dishData(dishData);
    			
    			// FIXME: hack; no single-quotes in name
				String finalName = null;
				if(dishData.getRestaurantName() != null) {
					finalName = dishData.getRestaurantName();
				} else if(recommendation.getRestaurantName() != null) {
					finalName = recommendation.getRestaurantName();
				}
				
				if(finalName != null) {
					finalName = finalName.replace("'", "");
					builder.restaurantName(finalName);
				} else {
				    return null;
				}
				
                // FIXME: hack; hard-coded comments
				List<String> comments = dishData.getComments();
				if(comments == null) {
				    comments = new ArrayList<String>();
				}
				comments.add("Dr. Helal:    A must-do anytime you're in TitleTown, USA!");
				builder.comments(comments);
    			
    			// FIXME: hack; hard-coded the mapUrl to be in gainesville, fl
				final String startingLocation = "gainesville+fl";
				final String endingLocation = finalName.replace(" ", "+");
				builder.mapUrl("https://maps.google.com/maps?hl=en&q=" + startingLocation + "+to+" + endingLocation + "+" + startingLocation);
    			
    			
    			finalRecommendation = builder.build();
    			
    			
    			/*recommendation.setCity(dishData.getCity());
    			recommendation.setState(dishData.getState());
    			recommendation.setZipcode(dishData.getZipcode());
    			recommendation.setStreetAddress(dishData.getStreetAddress());*/
    	//	}    		
    	}
        return finalRecommendation;
        
    
    }
    
    public static List<DishData> generateRecommendations(final long radiusMeters) {
        final List<DishData> finalList = new ArrayList<DishData>();
        
        ArrayList<DishData> restaurants = new LocationService().getNearbyRestaurants(radiusMeters);
        if(restaurants == null) return new ArrayList<DishData>();
        
        for(final DishData recommendation : restaurants) {
                DishData dishData = new LocationService().getRestaurantDetails(recommendation.getReference());
                
                if(dishData == null) continue;
                
                final DishData.Builder builder = new DishData.Builder()
                                                    .dishData(recommendation)
                                                    .dishData(dishData);
                
                // FIXME: hack; no single-quotes in name
                String finalName = null;
                if(dishData.getRestaurantName() != null) {
                    finalName = dishData.getRestaurantName();
                } else if(recommendation.getRestaurantName() != null) {
                    finalName = recommendation.getRestaurantName();
                }
                
                if(finalName != null) {
                    finalName = finalName.replace("'", "");
                    builder.restaurantName(finalName);
                } else {
                    continue;
                }
                
                // FIXME: hack; hard-coded comments
                List<String> comments = dishData.getComments();
                if(comments == null) {
                    comments = new ArrayList<String>();
                }
                comments.add("Dr. Helal:    A must-do anytime you're in TitleTown, USA!");
                builder.comments(comments);
                
                // FIXME: hack; hard-coded the mapUrl to be in gainesville, fl
                final String startingLocation = "gainesville+fl";
                final String endingLocation = finalName.replace(" ", "+");
                builder.mapUrl("https://maps.google.com/maps?hl=en&q=" + startingLocation + "+to+" + endingLocation + "+" + startingLocation);
                
                
                finalList.add(builder.build());
                
                
                /*recommendation.setCity(dishData.getCity());
                recommendation.setState(dishData.getState());
                recommendation.setZipcode(dishData.getZipcode());
                recommendation.setStreetAddress(dishData.getStreetAddress());*/
        //  }           
        }
        return finalList;
        
    
    }
}
